package lumis.service.wsrp.consumer;

import java.util.Properties;

import lumis.portal.PortalException;
import lumis.portal.UnexpectedException;
import lumis.portal.dao.DaoException;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.transaction.ITransaction;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.service.wsrp.consumer.producermanager.ClonedPortlet;
import lumis.service.wsrp.consumer.producermanager.ProducerEntityImpl;
import lumis.service.wsrp.consumer.producermanager.ProducerEntityManagerFactory;

import com.sun.portal.wsrp.common.stubs.v2.PortletDescription;
import com.sun.portal.wsrp.consumer.common.WSRPConsumerException;
import com.sun.portal.wsrp.consumer.producermanager.ProducerEntityManager;

/**
 * Portlet service manager.
 *
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class PortletServiceManager implements IPortletServiceManager
{
	private ProducerEntityImpl producerEntity;
	private RemotePortletManagementManager remotePortletManager;
	
	/**
	 * Constructor method for PortletServiceManager
	 * @param producerEntityId id of the producerEntity to retrive the PortletServiceManager for.
	 * @throws PortalException if the entity version is not correct.
	 */
	PortletServiceManager(String producerEntityId) throws PortalException
	{
		this.producerEntity = findProducerEntity(producerEntityId);
		
		RemoteServiceManagerFactory factory = new RemoteServiceManagerFactory();
		this.remotePortletManager = factory.getRemotePortletManagementManager(producerEntity);
	}	
	
	ProducerEntityImpl findProducerEntity(String producerEntityId) throws PortalException
	{
		ProducerEntityImpl producerEntity = null;

		ProducerEntityManager producerEntityManager = ProducerEntityManagerFactory.getProducerEntityManager(producerEntityId);
		try
		{
			// get producer entity
			if (!(producerEntityManager.getProducerEntityIds().isEmpty()))
			{
				producerEntity = (ProducerEntityImpl) producerEntityManager.getProducerEntity(producerEntityManager.getProducerEntityIds().iterator().next());
			}
			return producerEntity;
		}
		catch (WSRPConsumerException e)
		{
			throw new UnexpectedException(e);
		}
	}
	
	public String getPortletName(String portletHandle) throws PortalException
	{
		return this.remotePortletManager.getPortletName(portletHandle);
	}
	
	public String getDescriptionFromPortlet(String portletHandle)
					throws PortalException
	{
		return this.remotePortletManager.getDescriptionFromPortlet(portletHandle);
	}
	
	public String clonePortlet(String portletHandle, String friendlyName)
					throws PortalException
	{
		String clonedPortletHandle = this.remotePortletManager.clonePortlet(portletHandle);		
		addClonedPortlet(this.producerEntity.getId(), clonedPortletHandle, friendlyName);
		
		return clonedPortletHandle;
	}	
	
	public Properties getPortletProperties(String portletHandle)
						throws PortalException
	{
		return this.remotePortletManager.getPortletProperties(portletHandle);
	}
	
	public PortletDescription getPortletDescription(String portletHandle) 
							throws PortalException
	{
		return this.remotePortletManager.getPortletDescription(portletHandle);
	}
	
	public void setPortletProperties(String portletHandle,
									Properties properties)
					throws PortalException
	{
		this.remotePortletManager.setPortletProperties(portletHandle, properties);		
	}
	
	public void removeClone(String portletHandle) throws PortalException
	{
		this.remotePortletManager.removeClone(portletHandle);
		removeClonedPortlet(portletHandle);
	}
	
	/**
	 * Removes a cloned portlet from database if it exists
	 * @param cloneHandle
	 * @throws PortalException
	 */
	private void removeClonedPortlet(String cloneHandle) throws PortalException
	{
		
		try
		{
			ITransaction transaction = PortalTransactionFactory.createTransaction();
			try
			{
				transaction.begin();

				ClonedPortlet clonedPortlet = ManagerFactory.getEntityManager().find(ClonedPortlet.class, cloneHandle);
				if(clonedPortlet != null)
				{
					clonedPortlet.getRegistration().getClonedPortlets().remove(clonedPortlet);
					ManagerFactory.getEntityManager().remove(clonedPortlet);
				}
				transaction.commit();				
			}
			finally
			{
				transaction.dispose();
			}
		}
		catch (DaoException e)
		{
			throw new PortalException(e.getMessage(), e);
		}
	}
	
	private void addClonedPortlet(String producerEntityId,
									String portletHandle,
									String displayName)
					throws PortalException
	{
		ClonedPortlet cp = new ClonedPortlet(portletHandle, displayName);
		
		try
		{
			ITransaction transaction = PortalTransactionFactory.createTransaction();
			try
			{
				transaction.begin();
				ProducerEntityImpl producer = ManagerFactory.getEntityManager().find(ProducerEntityImpl.class, producerEntityId);
				producer.getRegistration().addClonedPortlet(cp);
				this.producerEntity = producer;
				transaction.commit();				
			}
			finally
			{
				transaction.dispose();
			}
		}
		catch (DaoException e)
		{
			throw new PortalException(e.getMessage(), e);
		}
	}
}